<template>
  <div class="lang-dialog__wrapper" v-if="dialogVisible">
    <div class="lang-dialog">
      <div class="lang-dialog__header">
        <div class="lang-dialog__title"><slot name="title">{{title}}</slot></div>
        <button type="button" class="lang-dialog-header-btn" @click="close"> <i class="lang-icon-close"></i> </button>
      </div>
      <div class="lang-dialog__body">
        <div class="tips" v-show="failed"><slot name="errorText">{{ errorText }}</slot></div>
        <div class="tips" v-show="success"><slot name="successText">{{ successText }}</slot></div>
        <div class="tips" v-show="!failed && !success"><slot name="tips">{{ tips }}</slot></div>

        <div class="rotate-body">
          <div class="rotate-bg">
            <img v-show="rotateImg" :src="rotateImg" alt="" :style="{'transform': 'rotate(' + rotateX + 'deg)'}"  :class="{'slider-shock':shock}">
            <div v-show="isMove" class="rotate-correcting" />
            <div v-show="loading || success || failed" class="rotate-mask" />
            <div
              class="rotate-icon"
              :class="[
                loading ? 'rotate-icon-loading':'',
                failed ? 'rotate-icon-error' : '',
                success ? 'rotate-icon-success' : ''
              ]"
            />
          </div>
          <div class="rotate-progress">
            <div class="rotate-progress-bottom" :class="{'slider-shock':shock}">
              <p v-show="!isSlider || rotateX === 0">拖动滑块使图片角度为正</p>
            </div>
            <div
              class="rotate-progress-btn"
              :style="{'left': rotateMoveLeft}"
              :class="[(!isSlider || rotateX === 0) ? 'rotate-btn-slider-up' :
                (loading ? 'rotate-btn-slider-loading' : (failed ? 'rotate-btn-slider-error' : 'rotate-btn-slider-active')),{'slider-shock':shock}, {'slider-start-shock': btnShock}]"
              @touchstart.passive="rotateTouchStart"
              @touchmove.passive="rotateTouchMove"
              @touchend.passive="rotateEnd"
              @mousedown="rotateStart"
            >
              <p :class="[(!isSlider || rotateX === 0) ? 'rotate-black' : 'rotate-white']" />
            </div>
          </div>
        </div>
        <div style="position:relative;">
          <div class="slider-refresh" style="font-size: 29px;" @click.stop="" @mouseenter="questionMessage = true" @mouseleave="questionMessage = false">
            <div class="slider-tools-btn lang-tips">
              <div class="lang-tips-item lang-tips-bottom" v-show="questionMessage">
                <slot name="question">
									<div v-if="question">{{question}}</div>
									<div v-else>
										拖动滑块使图片角度为正，欢迎提建议！
											<a href="https://gitee.com/langlanglang/poster" target="_blank">gitee</a>
											<a href="https://github.com/kkokk/poster" target="_blank">github</a>
									</div>
								</slot>
              </div>
              <img src="">
            </div>
          </div>
          <div class="slider-refresh" style="left: 35px;" @click.stop="refresh" @mouseenter="refreshMessage = true" @mouseleave="refreshMessage = false">
            <div class="slider-tools-btn lang-tips" style="width:24px;height: 24px;"> <!-- 刷新 -->
              <div class="lang-tips-item lang-tips-bottom" v-show="refreshMessage"> 刷新</div>
              <img src="">
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'RotateCaptcha',
    props:
    {
      value: {
        type: Boolean,
        default: false
      },
      modelValue: {
        type: Boolean,
        default: false
      },
      loading: {
        type: Boolean,
        default: false
      },
      title: {
        type: String,
        default: '安全验证'
      },
      tips: {
        type: String,
        default: '请完成下方验证'
      },
      successText: {
        type: String,
        default: '验证成功'
      },
      errorText:{
        type: String,
        default: '是不是太难了，咱换一个'
      },
      question: {
        type: String,
        default: ''
      },
      options: {
        type: Object,
        default() {
          return {
            rotateImg:'',
            rotateKey: ''
          }
        }
      }
    },
    watch: {
      value: {
        handler: function(val) {
          this.init(val)
        },
        immediate: true
      },
      modelValue: {
        handler: function(val) {
          this.init(val)
        },
        immediate: true
      },
      options: {
        handler: function(option) {
          this.clear()
          this.rotateImg = option.rotateImg
          this.rotateKey = option.rotateKey
        },
        deep:true,
        immediate: true
      }
    },
    data() {
      return {
        dialogVisible: false,
        btnShock: false,
        success: false,
        failed: false,
        rotateImg: '',
        rotateKey: '',
        rotateX: 0,
        rotateRate: 1.7,
        rotateWdtih: 212,
        isSlider: false,
        rotateMoveLeft: '0px',
        isMove: false,
        shock: false,
        tipEvents: {},
        rotateMoveX: 0,
        questionMessage: false,
        refreshMessage: false,
      }
    },
    methods: {
      init(open) {
        this.dialogVisible = open
        if(open) {
          this.btnShock = open
          setTimeout(() => {
            this.btnShock = false
          }, 1000)
          this.clear()
        }
      },
      clear() {
        this.success = false
        this.failed = false
        this.rotateImg = ''
        this.rotateKey = ''
        this.rotateX = 0
        this.rotateMoveLeft = '0px'
      },
      check(rotateKey, rotateX)
      {
        this.$emit('check', rotateKey, rotateX, this.done, this.error)
      },
      done()
      {
        this.success = true
      },
      error() {
        this.failed = true
        this.shock = true
        setTimeout(() => {
          this.shock = false
          this.isSlider = false
          this.rotateMoveLeft = '0px'
          this.$emit('error')
        }, 1000)
      },
      close() {
        this.dialogVisible = false
        this.$emit('input', this.dialogVisible)
        this.$emit('update:modelValue', this.dialogVisible)
        this.$emit('close')
      },
      refresh()
      {
        this.$emit('refresh')
      },
      rotateTouchStart(e) {
        // 移动触摸移动
        const that = this
        if(that.loading || that.failed || that.success) return
        const rotate = e.target
        that.rotateMoveX = e.touches[0].clientX - rotate.offsetLeft
        that.isSlider = true
        that.isMove = true
      },
      rotateTouchMove(e) {
        const that = this
        if(that.loading || that.failed || that.success) return
        let left = e.touches[0].clientX - that.rotateMoveX
        if (left >= 0 && left <= that.rotateWdtih) {
          if (left < 5) left = 0
          that.rotateMoveLeft = left + 'px'
          that.rotateX = left * that.rotateRate
        }
      },
      rotateEnd() {
        if(this.loading || this.failed || this.success) return
        this.isMove = false
        this.check(this.rotateKey, this.rotateX)
      },
      rotateStart(e) {
        var that = this
        if(that.loading || that.failed || that.success) return
        const rotate = e.target // 获取目标元素
        // 算出鼠标相对元素的位置
        const rotateX = e.clientX - rotate.offsetLeft

        that.isSlider = true
        that.isMove = true
        document.onmousemove = (e) => {
          let left = e.clientX - rotateX
          if (left >= 0 && left <= that.rotateWdtih) {
            if (left < 5) left = 0
            that.rotateMoveLeft = left + 'px'
            that.rotateX = left * that.rotateRate
            // console.log(that.rotateX)
          }
        }

        document.onmouseup = () => {
          // console.log('放开了我')
          that.isMove = false
          document.onmousemove = null
          document.onmouseup = null
          this.check(this.rotateKey, this.rotateX)
        }
      }
    }
  }
</script>

<style scoped>
a + a {
	margin-left: 10px;
}
/* 弹窗开始  */
.lang-dialog__wrapper {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  overflow: hidden;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .5);
  text-align: left;
  z-index: 88888888;
}

.lang-dialog {
  position: relative;
  margin: 0 auto 50px;
  border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 30%);
  box-sizing: border-box;
  background: #FFF;
  width: 50%;
  margin-top: calc(50vh - 185px);
  width: 305px;
}

.lang-dialog__header {
  padding: 20px 10px 10px;
}

.lang-dialog__title {
  line-height: 20px;
  font-size: 18px;
  color: #525252;
}

.lang-dialog-header-btn {
  position: absolute;
  top: 20px;
  right: 20px;
  padding: 0;
  background: 0 0;
  border: none;
  outline: 0;
  cursor: pointer;
  font-size: 16px
}

.lang-icon-close {
  color: rgba(0, 0, 0, 0.68);
  font-size: 20px;
}

.lang-icon-close:before {
  content: '×';
}

.lang-icon-close:hover {
  color: rgba(0, 0, 0, 0.88);
}

.lang-dialog__body {
  padding: 0 10px;
  color: #828282;
  font-size: 14px;
  word-break: break-all;
  height: 355px;
}

.loading-transparent-mask{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: transparent;
  z-index: 999;
}

/* 弹窗结束  */
/* loading start */
.loading-body {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.6);
  z-index: 999;
}

.loading {
  position: relative;
  display: inline-block;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border-top: 2px solid transparent;
  border-bottom: 2px solid transparent;
  border-left: 2px solid #409eff;
  border-right: 2px solid #409eff;
  animation: loading 1s infinite linear;
}

@keyframes loading {
  to {
    transform: rotate(360deg);
  }
}

.slider-loading {
  position: absolute;
  top: calc(50% - 15px);
  left: calc(50% - 15px);
  z-index: 999;
}

/* loading end */

.tips {
  color: #525252;
  line-height: 36px;
  font-size: 18px;
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rotate-body{
  position: relative;
  width: 100%;
  height: 255px;
}
.rotate-bg {
  position: relative;
  overflow: hidden;
  width: 152px;
  height: 152px;
  margin: 28px auto 24px;
  border: 0;
  -webkit-background-size: 100% 100%;
  background-size: 100% 100%;
}
.rotate-bg img {
  position: relative;
  z-index: 9;
  width: 100%;
  height: 100%;
  pointer-events: none;
  -webkit-border-radius: 50%;
  border-radius: 50%;
}
.rotate-bg .rotate-correcting {
  position: absolute;
  z-index: 10;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-image: url('');
  -webkit-background-size: 100% 100%;
  background-size: 100% 100%;
  background-repeat: no-repeat;
}
.rotate-bg .rotate-mask{
  position: absolute;
  z-index: 10;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: .5;
  -webkit-border-radius: 50%;
  border-radius: 50%;
  background: #000;
}
.rotate-bg .rotate-icon{
  position: absolute;
  z-index: 11;
  top: 50%;
  left: 50%;
}
.rotate-progress{
  position: relative;
  width: 260px;
  height: 50px;
  margin: 0 auto;
}
.rotate-progress .rotate-progress-bottom{
  position: absolute;
  top: 0;
  left: 0;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  -webkit-border-radius: 100px;
  border-radius: 100px;
  background: #f5f5f5;
  overflow: hidden;
}
.rotate-progress-bottom p{
  position: absolute;
  top: 50%;
  left: 50%;
  height: 22px;
  text-align: center;
  letter-spacing: -.36px;
  color: #4A4A4A;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  line-height: 21px;
  background: #b8b8b8 linear-gradient(to left, transparent, #111 90%, transparent) no-repeat 0 0;
  background-size: 20% 100%;
  background-clip: text;
  text-decoration: none;
  -webkit-text-fill-color: transparent;
  transform: translate(-40%,-50%)!important;
  width: 174px;
  margin: 0!important;
  opacity: 1!important;
  font-size: 14px!important;
  animation: slideShine 2s linear infinite;
}
.rotate-progress-btn {
  position: absolute;
  left: 0;
  top: 0;
  width: 50px;
  height: 50px;
  border-radius: 50px;
  background: #fff;
  box-shadow: 0 21px 52px 0 rgba(82, 82, 82, 20%);
  cursor: pointer;
  -moz-user-select: none;
  -o-user-select:none;
  -khtml-user-select:none;
  -webkit-user-select:none;
  -ms-user-select:none;
  user-select:none;
  -moz-user-drag: none;
  -webkit-user-drag: none;
}
.rotate-progress-btn p{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 22px;
  height: 22px;
  margin-left: -11px;
  margin-top: -11px;
  -webkit-background-size: 100% 100%;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  -moz-user-select: none;
  -o-user-select:none;
  -khtml-user-select:none;
  -webkit-user-select:none;
  -ms-user-select:none;
  user-select:none;
  -moz-user-drag: none;
  -webkit-user-drag: none;
  pointer-events: none;
  display: inline-block;
  vertical-align: middle;
}
.rotate-black {
  background-image: url('');
}

.rotate-white {
  background-image: url('');
}

.rotate-btn-slider-up{
  background: #fff;
  border: 1px solid #fff;
}

.rotate-btn-slider-active{
  background: #4E6EF2!important;
  border: 1px solid #4E6EF2;
}

.rotate-btn-slider-loading {
  background: #b8b8b8!important;
  border: 1px solid #b8b8b8;
}

.rotate-btn-slider-error{
  background: rgb(230, 65, 65)!important;
  border: 1px solid rgb(230, 65, 65);
}

.rotate-success {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 4;
  background: hsla(0,0%,100%,.8);
}
.rotate-success-icon {
  width: 64px;
  height: 64px;
  margin: 15% auto 0;
  
}
.rotate-success-icon img {
  width: 100%;
}
.rotate-success-icon .rotate-success-text {
  color: #1bc300;
  text-align: center;
  margin-top: 16px;
  font-size: 18px;
}
.rotate-icon-success{
  width:66px;
  height:66px;
  margin-left:-33px;
  margin-top:-33px;
  background-image:url('');
  -webkit-background-size:100% 100%;
  background-size:100% 100%;
  background-repeat:no-repeat
 }
.rotate-icon-error{
  width:66px;
  height:66px;
  margin-left:-33px;
  margin-top:-33px;
  background-image:url('');
  -webkit-background-size:100% 100%;
  background-size:100% 100%;
  background-repeat:no-repeat
 }
.rotate-icon-loading{
  width:75px;
  height:41px;
  margin-left:-38px;
  margin-top:-20px;
  background-image:url('');
  -webkit-background-size:100% 100%;
  background-size:100% 100%;
  background-repeat:no-repeat
 }

/* tips */
.slider-refresh {
  position: absolute;
  cursor: pointer;
  left: 0px;
  top: 0px;
  z-index: 2;
  font-size: 30px;
  height: 30px;
  line-height: 30px;
}
.slider-tools-btn {
  position: relative;
  width: 25px;
  height: 25px;
}

.lang-tips a {
  text-decoration: none;
  color: #409eff;
}

.lang-tips-item {
  position: fixed;
  font-size: 14px;
  color: #525252;
  max-width: 285px;
  margin-top: 40px;
  margin-left: 0;
  background: white;
  padding: 7px 10px;
  border-radius: 4px;
	margin-left: -8px;
}

.lang-tips-left {
  margin-top: -10px;
  margin-left: -140px;
}

.lang-tips-left:after {
  content: "";
  position: absolute;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
  border-left: 10px solid #000;
  border-right: 10px solid transparent;
  right: -18px;
  top: 12px;
}

.lang-tips-bottom {
  margin-top: 50px;
}

.lang-tips-bottom:after {
  content: "";
  position: absolute;
  border-top: 10px solid transparent;
  border-bottom: 10px solid #fff;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  /* right: calc(50% - 10px); */
  left: 10px;
  top: -20px;
}
.slider-tools-btn img {
  width: 100%;
  height: 100%;
}
/* tips */

.rotate-shock {
    animation-delay: 0s;
    animation-name: shock;
    animation-duration: .1s;
    animation-iteration-count: 5;
    animation-direction: normal;
    animation-timing-function: linear;
}

.slider-shock {
  animation-delay: 0s;
  animation-name: shock;
  animation-duration: .1s;
  animation-iteration-count: 5;
  animation-direction: normal;
  animation-timing-function: linear;
}
.slider-start-shock{
  animation-delay: 0s;
  animation-name: startShock;
  animation-duration: .8s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-timing-function: ease-in-out;
}
@keyframes shock {
    0% {
        margin-left: 2px;
    }
    100% {
        margin-left: -2px;
    }
}
@keyframes startShock {
    0% {
        margin-left: 18px;
    }
    20% {
        margin-left: 0px;
    }
    40% {
        margin-left: 8px;
    }
    60% {
      margin-left: 0px;
    }
    80% {
      margin-left: 4px;
    }
    100% {
        margin-left: 0px;
    }
}
@keyframes slideShine{
  0%{
      background-position:0 0
  }
  100%{
      background-position:100% 100%
  }
}
</style>